<?php
/**
 * 文件上传类
 * 
 * @version $Id: Upload.php 198 2011-06-18 02:36:01Z linsir123 $
 */
class comUpload
{
	/**
	 * @var 允许上传数据类型集合
	 */
	static $__mimes = array(
		'IMAGE' => array(
			'jpg|jpeg'				=> 'image/jpeg',
			'gif' 					=> 'image/gif',
			'png' 					=> 'image/png'
		),
		'VIDEO' => array(
			'mpg|mpeg' 				=> 'video/mpeg4-generic',
			'flv' 					=> 'flv-application/octet-stream'
		),
		'MUSIC' => array(
			'mp3|m4a'				=> 'audio/mpeg',
			'mid|midi'				=> 'audio/midi',
			'wma'					=> 'audio/wma'
		),
		'FLASH' => array(
			'swf'					=> 'application/x-shockwave-flash'
		),
		'DOCUMENT' => array(
			'pdf'					=> 'application/pdf',
			'doc|docx'				=> 'application/msword',
			'xla|xls|xlsx|xlt|xlw'	=> 'application/vnd.ms-excel',
			'zip'					=> 'application/zip',
			'rar'					=> 'application/x-rar-compressed'
		)
	);
	
	/**
	 * @var 允许上传数据类型
	 */
	public $mimes = array();
	
	/**
	 * @var 上传文件原始数据
	 */
	public $file = array();
	
	///
	public $code = 0;
	public $message;
	public $saveDir;
	public $fileName;
	public $fileExt;
	
	/**
	 * 构造函数
	 */
	public function __construct($size = 20971520, $type = 'IMAGE', $key = null)
	{
		if (empty($type)) {
			foreach (self::$__mimes as $val) 
				$this->mimes = array_merge($this->mimes, $val);
		} else 
			$this->mimes = self::$__mimes[$type];
			
		$this->_checkFile($key);
		$this->fileName = md5(uniqid(rand().microtime()));
	}
	
	/**
	 * 验证上传文件
	 */
	private function _checkFile($key = null)
	{
		try {
			if (empty($_FILES) || strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') 
				throw new Exception("请求数据为空或非法请求", 4);
				
			///
			if (isset($key)) {
				$this->file = $_FILES[$key];
				unset($_FILES[$key]);
			} else 
				$this->file = array_shift($_FILES);
				
			///
			if (!is_uploaded_file($this->file['tmp_name']) || $this->file['error'] != UPLOAD_ERR_OK) {
				switch ($this->file['error']) {
					case UPLOAD_ERR_INI_SIZE:
					case UPLOAD_ERR_FORM_SIZE:
						throw new Exception("文件大小限制", 4);
						
					case UPLOAD_ERR_NO_FILE:
						throw new Exception("没有文件被上传", 1);
						
					default:
						throw new Exception("文件上传到服务器失败", 2);
				}
			}
			
			///
			foreach ($this->mimes as $ext => $mime) {
				if (preg_match('!\.('.$ext.')$!i', strtolower($this->file['name']), $m)) {
					$this->fileExt = strtolower($m[1]);
					break;
				}
			}
			
			///
			if (preg_match('/^(jpg|jpeg|gif|png)$/i', $this->fileExt) && $imageInfo = getimagesize($this->file['tmp_name'])) {
				$exts = array_search($imageInfo['mime'], $this->mimes);
				if ($exts === false) 
					throw new Exception("图像资源格式有误", 5);
			}
			
			///
			if (empty($this->fileExt)) 
				throw new Exception("文件类型限制", 3);
				
			///
			if ($this->file['size'] <= 0 || $this->file['size'] > $size) 
				throw new Exception("文件大小限制", 4);
			
		} catch (Exception $e) {
			$this->code = $e->getCode();
			$this->message = $e->getMessage();
		}
	}
	
	/**
	 * 取得异常代码
	 */
	public function getCode()
	{
		return $this->code;
	}
	
	/**
	 * 取得异常信息
	 */
	public function getMessage()
	{
		return $this->message;
	}
	
	/**
	 * 设置上传类型
	 */
	function setMimes($mimes)
	{
		$this->mimes = $mimes;
	}
	
	/**
	 * 设置上传目录
	 */
	public function setDir($saveDir)
	{
		$saveDir = str_replace(array('/', '\\'), DS, $saveDir);
		$this->saveDir = ((substr($saveDir, -1) == DS) ? substr($saveDir, 0, -1) : $saveDir).DS;
	}
	
	/**
	 * 保存文件
	 */
	public function save($fileName = null)
	{
		$fileName or $fileName = $this->fileName;
		return empty($this->code) ? 
			move_uploaded_file($this->file['tmp_name'], $this->saveDir.$fileName.'.'.$this->fileExt) : false;
	}
}
